package net.arogarth.aws.android.manager.views;

import java.util.ArrayList;
import java.util.List;

import net.arogarth.aws.android.lib.AmazonEc2;
import net.arogarth.aws.android.lib.AmazonRoute53;
import net.arogarth.aws.android.lib.AwsRequestException;
import net.arogarth.aws.android.lib.AwsSettings;
import net.arogarth.aws.android.lib.models.AvailabilityZoneInfo;
import net.arogarth.aws.android.lib.models.RegionInfo;
import net.arogarth.aws.android.manager.AwsManager;
import net.arogarth.aws.android.manager.DatabaseAdapter;
import net.arogarth.aws.android.manager.R;
import net.arogarth.aws.android.manager.dbmodels.Region;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

/**
 * The Main-Menu of the AWS-Manager
 * 
 * @author arogarth
 * 
 */
public class Main extends Activity {

	/**
	 * The List adapter for the Menu-Icons
	 * 
	 * Size of the arrays labels and images must be the same. The Image for
	 * labels[x] is images[x]
	 * 
	 * Example: labels[1] as the Image images[1] etc.
	 * 
	 * @author arogarth
	 * 
	 */
	private class MainViewListAdapter extends BaseAdapter implements
			AdapterView.OnItemClickListener {
		private String[] labels = { "EC2", "Snapshots", "RDS", "AMI", "EBS",
				"ELB", "ElasticIp", "Route53" };

		private Integer[] images = { R.drawable.desktop,
				R.drawable.file_locked, R.drawable.database,
				R.drawable.chardevice, R.drawable.hdd_unmount, R.drawable.globe, R.drawable.socket, R.drawable.route53 };

		private Context context;

		public MainViewListAdapter(Context view, GridView list) {
			list.setAdapter(this);
			list.setOnItemClickListener(this);

			this.context = view;
		}

		public int getCount() {
			return labels.length;
		}

		public String getItem(int position) {
			return labels[position];
		}

		public long getItemId(int position) {
			return position;
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			final LinearLayout _ll = (LinearLayout) LayoutInflater.from(
					this.context).inflate(R.layout.main_imagetext_button,
					parent, false);

			((TextView) _ll.findViewById(R.id.buttonText))
					.setText(this.labels[position]);
			((ImageView) _ll.findViewById(R.id.buttonImage))
					.setImageResource(this.images[position]);

			return _ll;
		}

		public void onItemClick(AdapterView<?> arg0, View arg1, int position,
				long arg3) {
			if (getItem(position).equalsIgnoreCase("ec2")) {
				startActivity(new Intent(Main.this, Ec2InstanceList.class));
			} else if (getItem(position).equalsIgnoreCase("snapshots")) {
				startActivity(new Intent(Main.this, Ec2SnapshotList.class));
			} else if (getItem(position).equalsIgnoreCase("rds")) {
				startActivity(new Intent(Main.this, RdsDbInstanceList.class));
			} else if (getItem(position).equalsIgnoreCase("ami")) {
				startActivity(new Intent(Main.this, Ec2AmiList.class));
			} else if (getItem(position).equalsIgnoreCase("ebs")) {
				startActivity(new Intent(Main.this, Ec2EbsList.class));
			} else if (getItem(position).equalsIgnoreCase("elb")) {
				startActivity(new Intent(Main.this, ElbList.class));
			} else if (getItem(position).equalsIgnoreCase("ElasticIp")) {
				startActivity(new Intent(Main.this, ElIpList.class));
			} else if (getItem(position).equalsIgnoreCase("Route53")) {
				startActivity(new Intent(Main.this, Route53HostetZoneList.class));
			}
		}
	}

	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.main);
		GridView gv = (GridView) findViewById(R.id.mainGrid);

		new MainViewListAdapter(Main.this, gv);

		/**
		 * Set AWS Settings
		 */
		AwsSettings.setAwsRegion(AwsManager.getCurrentAwsAccount()
				.getDefaultRegion());
		AwsSettings.setAccessKey(AwsManager.getCurrentAwsAccount()
				.getAccessKey());
		AwsSettings.setSecretKey(AwsManager.getCurrentAwsAccount()
				.getSecretKey());

		preloadData();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.main_menu, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {

		case R.id.itmSelectRegion:
			showRegionPopup();

			break;
		default:
			return super.onOptionsItemSelected(item);
		}

		return true;
	}

	/**
	 * Popup a list of available Regions from AWS given in the Database
	 */
	private void showRegionPopup() {
		@SuppressWarnings("unchecked")
		List<Region> regions = (List<Region>) new Region().list();

		final List<String> strRegions = new ArrayList<String>();
		for (Region region : regions)
			strRegions.add(region.getRegion());

		AlertDialog.Builder builder = new AlertDialog.Builder(Main.this);
		builder.setTitle("Regions");

		final ArrayAdapter<String> adapter = new ArrayAdapter<String>(
				Main.this, android.R.layout.simple_spinner_dropdown_item,
				strRegions);

		builder.setAdapter(adapter, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				String region = strRegions.get(which);

				AwsManager.getCurrentAwsAccount().setDefaultRegion(region);
				AwsManager.getCurrentAwsAccount().save();

				AwsSettings.setAwsRegion(region);
			}
		});

		builder.create().show();
	}

	/**
	 * Load the Region that are available
	 * 
	 * Poped and locked the GUI up if no default region is defined. Otherwise it
	 * will load the list in Background
	 * 
	 */
	private void preloadData() {
		boolean hasDefaultRegion = false;

		if (!AwsManager.getCurrentAwsAccount().getDefaultRegion().equals("")) {
			AwsSettings.setAwsRegion(AwsManager.getCurrentAwsAccount()
					.getDefaultRegion());
			hasDefaultRegion = true;
		}

		final ProgressDialog pd = ProgressDialog.show(Main.this,
				"Please wait...", "Loading Data...", false, false);

		if (hasDefaultRegion)
			pd.dismiss();

		final boolean _hasDefaultRegion = hasDefaultRegion;

		Thread t = new Thread() {
			@Override
			public void run() {
				try {
					AmazonEc2 aec2 = new AmazonEc2();

					DatabaseAdapter dba = new DatabaseAdapter(
							getApplicationContext()).open();

//					AwsSettings.setAwsRegion("");
					
					// Fetch all Regions
					List<RegionInfo> regions = aec2.describeRegions();
					dba.getDatabase().execSQL(
							String.format(
									"DELETE FROM %s WHERE account_id = %s",
									DatabaseAdapter.APP_DB_TABLE_REGIONS,
									AwsManager.getCurrentAwsAccount().getId()));
					dba.getDatabase()
							.execSQL(
									String.format(
											"DELETE FROM %s WHERE id > 0",
											DatabaseAdapter.APP_DB_TABLE_AVAILABLE_ZONES));
					Log.d("SQL", "Regions and Zones deleted");

					for (RegionInfo region : regions) {
						// Insert regions to Database
						dba.getDatabase()
								.execSQL(
										String.format(
												"INSERT INTO %s (account_id, region) VALUES (%s, '%s')",
												DatabaseAdapter.APP_DB_TABLE_REGIONS,
												AwsManager
														.getCurrentAwsAccount()
														.getId(), region
														.getRegionName()));
					}
						
					// fetch the zone
					List<AvailabilityZoneInfo> zones = aec2
							.describeAvailabilityZones();
					
					for (AvailabilityZoneInfo zone : zones) {
						// add zone to database with state its region
						String qry = String.format(
								"INSERT INTO %s (account_id, region, zone, state) VALUES ('%s', '%s', '%s', '%s')",
								DatabaseAdapter.APP_DB_TABLE_AVAILABLE_ZONES,
								AwsManager.getCurrentAwsAccount().getId(),
								zone.getRegionName(),
								zone.getZoneName(),
								zone.getZoneState());
						
						Log.d("QUERY", qry);
						
						dba.getDatabase().execSQL(qry);
					}
						
					dba.close();
					Log.d("REQUEST",
							"############# FINISHED #####################");

					runOnUiThread(new Runnable() {
						public void run() {
							pd.dismiss();

							if (!_hasDefaultRegion)
								showRegionPopup();
						}
					});
				} catch (AwsRequestException e) {
				}
			}
		};
		t.start();
	}
}
